package cn.innosmart.aq.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.zhy.autolayout.utils.AutoUtils;

import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import cn.innosmart.aq.R;
import cn.innosmart.aq.application.AQApplication;
import cn.innosmart.aq.bean.AlarmConditionBean;
import cn.innosmart.aq.bean.AquariumBean;
import cn.innosmart.aq.bean.DeviceBean;
import cn.innosmart.aq.camera.models.CameraBean;
import cn.innosmart.aq.camera.protocol.Camera;
import cn.innosmart.aq.util.AppUtil;
import cn.innosmart.aq.util.DeviceConstant;
import cn.innosmart.aq.util.SystemConstant;

/**
 * Created by David on 2015/11/17.
 */
public class DeviceGridViewAdapter extends BaseAdapter {
    private final int mIconSize;
    private LayoutInflater mInflater;
    private Context mContext;
    private ArrayList<String> devices = new ArrayList<>();
    private View.OnClickListener onNormalIconClickListener;
    private View.OnClickListener onAlarmIconClickListener;
    private View.OnClickListener onNameClickListener;
    private View.OnClickListener onControlClickListener;
    private Camera.OnStreamInfoUpdate onStreamInfoUpdate = new Camera.OnStreamInfoUpdate() {

        @Override
        public void onFrameRateUpdate(String frameRate) {

        }

        @Override
        public void onFrameResolutionUpdate(String resolution) {

        }

        @Override
        public void onCameraConnected() {

        }


        @Override
        public void onCameraStatus(String did, int status) {
            final CameraBean cameraBean = SystemConstant.cameraBeanHashMap.get(did);
            cameraBean.setStatus(status);
            notifyDataSetChanged();
        }
    };
    private View.OnClickListener onValueClickListener;

    /**
     * @param context
     * @param aquariumBean 要显示设备列表的鱼缸
     */
    public DeviceGridViewAdapter(Context context, AquariumBean aquariumBean) {
        mInflater = LayoutInflater.from(context);
        mContext = context;
        mIconSize = context.getResources().getDimensionPixelSize(R.dimen.drawer_icon_size);//24dp
        devices.add("AQGW");
        devices.addAll(aquariumBean.getDeivices());
        devices.addAll(aquariumBean.getCameras());
        ArrayList<String> address = aquariumBean.getCameras();
        for (String cameraid : address) {
            CameraBean cameraBean = SystemConstant.cameraBeanHashMap.get(cameraid);

            if (!AppUtil.getInstance().isEmulator()) {
                cameraBean.initCameraDevice(mContext, onStreamInfoUpdate);
            }
        }

    }

    @Override
    public int getCount() {
        return devices.size();
    }

    @Override
    public Object getItem(int position) {
        return devices.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }


    private Lock l = new ReentrantLock(true);

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        l.lock();

        String address = devices.get(position);

        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.gridview_device, null);
            holder.configAlarmButton = (TextView) convertView.findViewById(R.id.config_button);
            holder.deviceIcon = (ImageView) convertView.findViewById(R.id.device_icon);
            holder.deviceName = (TextView) convertView.findViewById(R.id.device_name);
            holder.deviceStatus = (TextView) convertView.findViewById(R.id.device_status);
            holder.switchBottom = (LinearLayout) convertView.findViewById(R.id.switch_bottom);
            holder.rlLeft = (RelativeLayout) convertView.findViewById(R.id.rl_left);
            holder.rlRight = (RelativeLayout) convertView.findViewById(R.id.rl_right);
            holder.leftButton = (TextView) convertView.findViewById(R.id.left_button);
            holder.line_1 = convertView.findViewById(R.id.line_1);
            holder.rightButton = (TextView) convertView.findViewById(R.id.right_button);
            holder.line_2 = convertView.findViewById(R.id.line_1);
            holder.detechBottom = (LinearLayout) convertView.findViewById(R.id.detech_bottom);
            holder.middleButton = (TextView) convertView.findViewById(R.id.middle_button);
            convertView.setTag(holder);
            AutoUtils.autoSize(convertView);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.alarmType = 0;

        if (address.equals("AQGW")) {
            holder.configAlarmButton.setVisibility(View.GONE);
            holder.deviceName.setText(R.string.gateway_string);
            holder.deviceIcon.setImageResource(R.drawable.gw);
            holder.deviceStatus.setText(R.string.gw_online);
            holder.switchBottom.setVisibility(View.GONE);
            holder.leftButton.setVisibility(View.GONE);
            holder.line_1.setVisibility(View.GONE);
            holder.middleButton.setVisibility(View.VISIBLE);
            holder.middleButton.setText(R.string.gw_online_setting);
            holder.middleButton.setOnClickListener(onControlClickListener);
            holder.rightButton.setVisibility(View.GONE);
            holder.line_2.setVisibility(View.GONE);
            holder.detechBottom.setVisibility(View.VISIBLE);

            DeviceBean deviceBean = new DeviceBean();
            deviceBean.setAddress("AQGW");
            holder.middleButton.setTag(deviceBean);

            holder.alarmType = 9;

            holder.deviceName.setOnClickListener(null);
            holder.deviceStatus.setOnClickListener(null);

            holder.deviceIcon.setOnClickListener(onAlarmIconClickListener);
            holder.deviceIcon.setTag(R.string.alarmType, holder.alarmType);

            l.unlock();
            return convertView;
        }

        if (SystemConstant.deviceBeanHashMap.containsKey(address)) {
            DeviceBean deviceBean = SystemConstant.deviceBeanHashMap.get(address);

            int functype = deviceBean.getFunctype();
            if (deviceBean.isDeepAlarm()) {
                holder.deviceIcon.setImageResource(R.drawable.deep_alarm_icon);
            } else if (deviceBean.isAlarm()) {
                holder.deviceIcon.setImageResource(R.drawable.alarm_icon);
            } else {
                int resId = AQApplication.getChannelDrawableRes(mContext, functype);
                holder.deviceIcon.setImageResource(resId);
            }
            holder.deviceIcon.setTag(deviceBean);
            if (functype == DeviceConstant.FUNCTYPE_SWITCH) {
                holder.switchBottom.setVisibility(View.VISIBLE);
                holder.detechBottom.setVisibility(View.GONE);
            } else {
                holder.switchBottom.setVisibility(View.GONE);
                holder.detechBottom.setVisibility(View.VISIBLE);
            }
            if (functype == DeviceConstant.FUNCTYPE_WATERLEVER) {
                if (deviceBean.isSensorValueIsSet()) {
                    switch ((int) deviceBean.getSensorvalue()) {
                        case 0:
                            holder.deviceStatus.setText(R.string.water_lever_value_normal);
                            holder.alarmType = 0;
                            break;
                        case 1:
                            holder.deviceStatus.setText(R.string.water_lever_value_low);
                            holder.alarmType = 1; //low water level
                            break;
                        case 2:
                            holder.deviceStatus.setText(R.string.water_lever_value_high);
                            holder.alarmType = 2; //high water level
                            break;
                    }
                } else {
                    holder.deviceStatus.setText(R.string.status_device_no_report);
                    holder.deviceIcon.setImageResource(R.drawable.alarm_icon);
                    holder.alarmType = 7; //device no report

                }
                holder.middleButton.setText(R.string.water_lever_alarm);
            } else if (functype == DeviceConstant.FUNCTYPE_SWITCH) {
                System.out.println("check SWITCH");

                holder.leftButton.setText(R.string.switch_open);
                holder.rightButton.setText(R.string.switch_off);
                holder.configAlarmButton.setText(R.string.device_config);
                holder.detechBottom.setVisibility(View.GONE);

                if (deviceBean.isSensorValueIsSet()) {
                    if (deviceBean.getSensorvalue() == 255) {
                        holder.deviceStatus.setText(R.string.status_open);
                    } else if (deviceBean.getSensorvalue() == 0) {
                        holder.deviceStatus.setText(R.string.status_off);
                    }
                    holder.alarmType = 0;
                } else {
                    holder.deviceStatus.setText(R.string.status_device_no_report);
                    holder.deviceIcon.setImageResource(R.drawable.alarm_icon);
                    holder.alarmType = 7; //device no report
                }


                String slist[] = address.split("\\/");
                String wattDeviceBeanAddress = slist[0] + "//" + slist[2] + "/" + slist[3] + "/" + 50 + "/" + slist[5] + "/" + 2; // zwave://e5a00bee/3/50/3/2

                DeviceBean wattDeviceBean = SystemConstant.deviceBeanHashMap.get(wattDeviceBeanAddress);
                if (wattDeviceBean != null) {
                    AlarmConditionBean alarmConditionBean = DeviceConstant.alarmConditionBeanHashMap.get(wattDeviceBean.getAddress());
                    if (alarmConditionBean != null) {
//                        System.out.println("deviceBean.getSensorvalue()=" + deviceBean.getSensorvalue());
//                        System.out.println("wattDeviceBean.getSensorvalue()=" + wattDeviceBean.getSensorvalue());
//                        System.out.println("wattDeviceBean.oldAlarmType=" + wattDeviceBean.oldAlarmType);

                        if (wattDeviceBean.oldAlarmType == -1) {
                            //first
                            if (deviceBean != null && deviceBean.getSensorvalue() == 255 && wattDeviceBean.getSensorvalue() < 10 && wattDeviceBean.getSensorvalue() >= 0) {
                                //to check switch
                                wattDeviceBean.oldAlarmType = 8;
                            } else {
                                wattDeviceBean.oldAlarmType = 0;
                            }
                        }

                        if (wattDeviceBean.oldAlarmType > 0) {
                            holder.deviceIcon.setImageResource(R.drawable.alarm_icon);
                            holder.alarmType = wattDeviceBean.oldAlarmType; //low watt exception
                        } else if (wattDeviceBean.oldAlarmType == 0) {
                            holder.deviceIcon.setImageResource(R.drawable.switch_icon);
                            holder.alarmType = wattDeviceBean.oldAlarmType; //low watt exception
                        }
                    }
                }

                holder.switchBottom.setVisibility(View.VISIBLE);
                holder.rlLeft.setVisibility(View.VISIBLE);
                holder.leftButton.setVisibility(View.VISIBLE);
                holder.line_1.setVisibility(View.VISIBLE);

                holder.rlRight.setVisibility(View.VISIBLE);
                holder.rightButton.setVisibility(View.VISIBLE);
                holder.line_2.setVisibility(View.VISIBLE);

                holder.configAlarmButton.setVisibility(View.VISIBLE);

            } else if (functype == DeviceConstant.FUNCTYPE_TEMPERATURE) {
                double value = deviceBean.getSensorvalue();
                int sensorunity = deviceBean.getSensorunit();
                if (deviceBean.isSensorValueIsSet()) {
                    if (deviceBean.getSensorvalue() == 0.0) {
                        holder.deviceStatus.setText(R.string.status_device_no_report);
                        holder.alarmType = 7; //device no report
                    } else {
                        holder.deviceStatus.setText(DeviceConstant.caculateValue(1, value));
                        holder.alarmType = 0;
                    }
                } else {
                    holder.deviceStatus.setText(R.string.status_device_no_report);
                    holder.deviceIcon.setImageResource(R.drawable.alarm_icon);
                    holder.alarmType = 7; //device no report
                }
                StringBuilder sb = new StringBuilder();
                if (DeviceConstant.alarmConditionBeanHashMap != null) {
                    AlarmConditionBean alarmConditionBean = DeviceConstant.alarmConditionBeanHashMap.get(deviceBean.getAddress());
                    if (alarmConditionBean != null) {
                        sb.append(String.format(mContext.getString(R.string.temperature_value_condition), alarmConditionBean.getAboveValue() / 10.0, alarmConditionBean.getBelowValue() / 10.0));
                        if (deviceBean.getSensorvalue() > alarmConditionBean.getBelowValue()) {
                            holder.alarmType = 6; //high temperature
                        } else if (deviceBean.getSensorvalue() < alarmConditionBean.getAboveValue()) {
                            holder.alarmType = 5; //low temperature
                        }
                    }
                }
                holder.middleButton.setText(sb.length() == 0 ? mContext.getString(R.string.alarm_condition) : sb.toString());
                holder.detechBottom.setVisibility(View.VISIBLE);
                holder.middleButton.setVisibility(View.VISIBLE);
            } else if (functype == DeviceConstant.FUNCTYPE_PH) {
                double value = deviceBean.getSensorvalue();
                int sensorunity = deviceBean.getSensorunit();

                if (deviceBean.isSensorValueIsSet()) {
                    if (deviceBean.getSensorvalue() == 0.0) {
                        holder.deviceStatus.setText(R.string.status_device_no_report);
                        holder.deviceIcon.setImageResource(R.drawable.alarm_icon);
                        holder.alarmType = 7; //device no report
                    } else {
                        holder.deviceStatus.setText(DeviceConstant.caculateValue(sensorunity, value));
                        holder.alarmType = 0; //no alarm
                    }
                } else {
                    holder.deviceStatus.setText(R.string.status_device_no_report);
                    holder.deviceIcon.setImageResource(R.drawable.alarm_icon);
                    holder.alarmType = 7; //device no report
                }

                StringBuilder sb = new StringBuilder();
                if (DeviceConstant.alarmConditionBeanHashMap != null) {
                    AlarmConditionBean alarmConditionBean = DeviceConstant.alarmConditionBeanHashMap.get(deviceBean.getAddress());
                    if (alarmConditionBean != null) {
                        sb.append(alarmConditionBean.getAboveValue() + "~" + alarmConditionBean.getBelowValue());
                        System.out.println("values:" + deviceBean.getSensorvalue() + ", " + alarmConditionBean.getBelowValue() + ", " + alarmConditionBean.getAboveValue());
                        if (deviceBean.getSensorvalue() > alarmConditionBean.getBelowValue()) {
                            holder.alarmType = 4; //high ph
                        } else if (deviceBean.getSensorvalue() < alarmConditionBean.getAboveValue()) {
                            holder.alarmType = 3; //low ph
                        }
                    }
                }
                holder.middleButton.setText(sb.length() == 0 ? mContext.getString(R.string.alarm_condition) : sb.toString());
                holder.detechBottom.setVisibility(View.VISIBLE);
                holder.middleButton.setVisibility(View.VISIBLE);
            } else if (functype == DeviceConstant.FUNCTYPE_FEEDER) {
                double value = deviceBean.getSensorvalue();
                int sensorunity = deviceBean.getSensorunit();
                if (deviceBean.isSensorValueIsSet()) {
                    if (deviceBean.getSensorvalue() == 0.0) {
                        holder.deviceStatus.setText(R.string.status_off);
                    } else {
                        holder.deviceStatus.setText(R.string.status_feed);
                    }
                } else {
                    holder.deviceStatus.setText(R.string.status_off);
                }
                holder.middleButton.setText(R.string.feed);
                holder.detechBottom.setVisibility(View.VISIBLE);
            }

            holder.deviceName.setTag(deviceBean);
            holder.rlLeft.setTag(deviceBean);
            holder.rlRight.setTag(deviceBean);
            holder.configAlarmButton.setTag(deviceBean);
            holder.detechBottom.setTag(deviceBean);
            holder.middleButton.setTag(deviceBean);
            holder.deviceStatus.setTag(deviceBean);
//            holder.deviceName.setText(deviceBean.getName() + ":" + deviceBean.getAddress().split("/")[3]);
            holder.deviceName.setText(deviceBean.getName());

            holder.deviceStatus.setOnClickListener(this.onValueClickListener);
            holder.rlLeft.setOnClickListener(onControlClickListener);
            holder.rlRight.setOnClickListener(onControlClickListener);
            holder.configAlarmButton.setOnClickListener(onControlClickListener);
            holder.configAlarmButton.setEnabled(true);
            holder.detechBottom.setOnClickListener(onControlClickListener);
            holder.middleButton.setOnClickListener(onControlClickListener);

            holder.rightButton.setEnabled(true);
            holder.rlRight.setEnabled(true);

        } else if (SystemConstant.cameraBeanHashMap.containsKey(address)) {
            CameraBean cameraBean = SystemConstant.cameraBeanHashMap.get(address);
            holder.deviceIcon.setImageResource(R.drawable.camera_icon);
            holder.switchBottom.setVisibility(View.VISIBLE);
            holder.configAlarmButton.setEnabled(false);
            holder.detechBottom.setVisibility(View.GONE);
            holder.deviceName.setText(cameraBean.getTitle());
            holder.leftButton.setText(R.string.camera_check);
            holder.rightButton.setText(R.string.set);
            cameraBean.setTag(holder.deviceStatus);
            switch (cameraBean.getStatus()) {
                case com.tutk.IOTC.Camera.CONNECTION_STATE_CONNECTED:
                    holder.deviceStatus.setText(R.string.camera_status);
                    break;
                case com.tutk.IOTC.Camera.CONNECTION_STATE_NONE:
                case com.tutk.IOTC.Camera.CONNECTION_STATE_UNSUPPORTED:
                case com.tutk.IOTC.Camera.CONNECTION_STATE_TIMEOUT:
                case com.tutk.IOTC.Camera.CONNECTION_STATE_UNKNOWN_DEVICE:
                case com.tutk.IOTC.Camera.CONNECTION_STATE_CONNECTING:
                case com.tutk.IOTC.Camera.CONNECTION_STATE_CONNECT_FAILED:
                case com.tutk.IOTC.Camera.CONNECTION_STATE_DISCONNECTED:
                    holder.deviceStatus.setText(R.string.camera_status_offline);
                    break;
                case com.tutk.IOTC.Camera.CONNECTION_STATE_WRONG_PASSWORD:
                    holder.deviceStatus.setText(R.string.camera_status_wrong_password);
                    break;
                case 9:
                    holder.deviceStatus.setText(R.string.reboot);
                    break;
            }
            holder.rlLeft.setTag(cameraBean);
            holder.rlRight.setTag(cameraBean);
            holder.deviceName.setTag(cameraBean);
            holder.deviceIcon.setTag(cameraBean);
            holder.rlLeft.setOnClickListener(onControlClickListener);
            holder.rlRight.setOnClickListener(onControlClickListener);
            if (cameraBean.isShown()) {
                holder.leftButton.setText(R.string.camera_close);
                holder.rightButton.setEnabled(true);
                holder.rlRight.setEnabled(true);
            } else {
                holder.leftButton.setText(R.string.camera_check);
                holder.rlRight.setEnabled(false);
                holder.rightButton.setEnabled(false);
            }

            //Camera
//            holder.deviceIcon.setImageResource(R.drawable.deep_alarm_icon);
//            holder.deviceName.setText("HELLO");
//            holder.deviceStatus.setText(R.string.gw_online);

            holder.switchBottom.setVisibility(View.VISIBLE);
            holder.rlLeft.setVisibility(View.VISIBLE);
            holder.leftButton.setVisibility(View.VISIBLE);
            holder.line_1.setVisibility(View.VISIBLE);

            holder.rlRight.setVisibility(View.VISIBLE);
            holder.rightButton.setVisibility(View.VISIBLE);
            holder.line_2.setVisibility(View.VISIBLE);

            holder.configAlarmButton.setVisibility(View.VISIBLE);
            holder.configAlarmButton.setText("");

            holder.detechBottom.setVisibility(View.GONE);
            holder.middleButton.setVisibility(View.GONE);
            holder.middleButton.setText(R.string.gw_online_setting);
            //holder.middleButton.setOnClickListener(onControlClickListener);

            DeviceBean deviceBean = new DeviceBean();
            deviceBean.setAddress(address);
            holder.middleButton.setTag(deviceBean);

            holder.deviceStatus.setOnClickListener(null);

        }

        holder.deviceName.setOnClickListener(onNameClickListener);

        if (holder.alarmType != 0) {
            holder.deviceIcon.setOnClickListener(onAlarmIconClickListener);
            holder.deviceIcon.setTag(R.string.alarmType, holder.alarmType);
        } else {
            holder.deviceIcon.setOnClickListener(onNormalIconClickListener);
            holder.deviceIcon.setTag(R.string.alarmType, 0);
        }

        l.unlock();
        return convertView;
    }


    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }

    public void setOnNormalIconClickListener(View.OnClickListener onNormalIconClickListener) {
        this.onNormalIconClickListener = onNormalIconClickListener;
    }


    public void setOnAlarmIconClickListener(View.OnClickListener onAlarmIconClickListener) {
        this.onAlarmIconClickListener = onAlarmIconClickListener;
    }

    public void setOnNameClickListener(View.OnClickListener onNameClickListener) {
        this.onNameClickListener = onNameClickListener;
    }

    /**
     * 刷新数据
     *
     * @param aquariumBean
     */
    public void refreshData(AquariumBean aquariumBean) {
        devices.clear();

        devices.add("AQGW");
        for (String address : aquariumBean.getDeivices()) {
            DeviceBean deviceBean = SystemConstant.deviceBeanHashMap.get(address);
            if (deviceBean != null) {
                if (deviceBean.getFunctype() == DeviceConstant.FUNCTYPE_PH) {
                } else if (deviceBean.getFunctype() == DeviceConstant.FUNCTYPE_TEMPERATURE) {
                } else if (deviceBean.getFunctype() == DeviceConstant.FUNCTYPE_SWITCH) {
                } else if (deviceBean.getFunctype() == DeviceConstant.FUNCTYPE_WATERLEVER) {
                } else if (deviceBean.getFunctype() == DeviceConstant.FUNCTYPE_FEEDER) {
                } else {
                    continue;
                }

                devices.add(address);
            }

        }


//        devices.addAll(aquariumBean.getDeivices());
        devices.addAll(aquariumBean.getCameras());
        notifyDataSetChanged();
    }

    /**
     * 设置控制监听器
     *
     * @param onControlClickListener
     */
    public void setOnControlClickListener(View.OnClickListener onControlClickListener) {
        this.onControlClickListener = onControlClickListener;
    }

    public void setOnValueClickListener(View.OnClickListener onValueClickListener) {
        this.onValueClickListener = onValueClickListener;
    }

    static class ViewHolder {
        ImageView deviceIcon;
        TextView deviceName;
        TextView deviceStatus;
        LinearLayout switchBottom;
        RelativeLayout rlLeft;
        RelativeLayout rlRight;
        TextView leftButton;
        View line_1;
        TextView rightButton;
        View line_2;
        TextView configAlarmButton;
        LinearLayout detechBottom;
        TextView middleButton;
        int alarmType; //0->no alarm, 1->low water alarm, 2->high water alarm, 3->low ph alarm, 4->high ph alarm, 5->low temperature alarm, 6->high tempearture alarm, 7->device no report, 8->low watt
    }

}
